package com.lei.util;


import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author User
 */
public class TransBean {
	/**
	 * 根据request传来的参数Map，和指定的实体Bean的属性进行比较，将二者名称相同的参数转换成属性类型的值，
	 * 并调用相应的set方法给Bean的属性赋值，
	 *
	 * @param map=request.getParameterMap();
	 * @param obj 要填充的对象
	 *
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 */
	public static void populate(Object obj,Map<String,String[]> map){
		Set<String> keySet=map.keySet();
		Class objClass = obj.getClass();
		Field[] fields = objClass.getDeclaredFields();
        try {
            for(Field field:fields){
                String propName=field.getName();
                if(field.getType().isArray()|| "java.util.List".equals(field.getType().getName())){
                    if (map.get(propName) != null || map.get(propName + "[]") != null) {
                    	//如果数组中有多个元素
                        //如果参数是数组，则其名称可能为"xxx[]"（ajax传来的json对象参数）,所以要将后面的“[]”去掉再和属性名进行比较
                        field.setAccessible(true);
                        field.set(obj, convertArray(
                                map.get(propName) == null ? map.get(propName + "[]") : map.get(propName),
                                field.getType().getComponentType()));
                        //将字符串数组转换成该属性的数组类型并赋值getComponentType():获得数组中元素的类型
                    }
                }else {
					//如果值数组只有一个元素并且不为空
                    if (map.get(propName) != null && map.get(propName).length == 1 && map.get(propName)[0] != null) {
						//设置属性可访问
                    	field.setAccessible(true);
						//将字符串转换成该属性的类型并赋值
						field.set(obj, convert(map.get(propName)[0], field.getType()));
                    }
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

	public static  List populate(Class objClass,List<Map> listMapData){
		if(listMapData==null||listMapData.size()==0) {
			return null;
		}
		List list=new ArrayList();
		//获得该类型所有声明的属性
		Field[] fields = objClass.getDeclaredFields();
        try {
            for(Map map:listMapData) {
				//创建实体类对象
                Object obj=objClass.newInstance();
				//遍历所有属性
                for (Field field : fields) {
					//获得当前属性的名称
                    String propName = field.getName();
					//如果map中包含该属性
                    if (map.containsKey(propName)){
						//设置属性可访问
                        field.setAccessible(true);
						//给该属性设置值（这里将所有类型的值都转换成string，然后再转换成该属性对应的类型）
                        field.set(obj,convert(map.get(propName)==null?"":map.get(propName).toString(),field.getType()));
                    }
                }
                list.add(obj);
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return list;
	}


	/**
	 * 将传入的字符串参数转化成制定的数据类型,如果格式不匹配则返回null
	 *
	 * @param <T>
	 * @param param
	 *            要转换的参数字符串
	 * @param clas
	 *            转换的目标CLASS
	 * @return
	 */
	private static <T extends Serializable> T convert(String param, Class clas) {
		if (param == null || param == "" || clas == null) {
			return null;
		}
		// 获得要转换的数据类型名称
		String type = clas.getName();
		if ("java.lang.String".equals(type)) {
			return (T) param;
		}
		try {
			// 根据不同类型的属性，返回不同的结果，如果出现异常，则返回null
			if ("java.util.Date".equals(type)) {
				return (T) new Date(java.sql.Date.valueOf(param)
						.getTime());
			}
			if ("java.sql.Date".equals(type)) {
				return (T) java.sql.Date.valueOf(param);
			}
			if ("java.sql.Timestamp".equals(type)) {
				return (T) java.sql.Timestamp.valueOf(param);
			}
			if ("java.lang.Char".equals(type)) {
				return (T) Character.valueOf(param.charAt(0));
			}
			if ("java.lang.Integer".equals(type) || "int".equals(type)) {
				return (T) new Integer(param);
			}
			if ("java.lang.Double".equals(type) || "double".equals(type)) {
				return (T) new Double(param);
			}
			if ("java.lang.Float".equals(type) || "float".equals(type)) {
				return (T) new Float(param);
			}
			if ("java.lang.Byte".equals(type) || "boolean".equals(type)) {
				return (T) new Boolean(param);
			}
			if ("java.lang.Short".equals(type) || "short".equals(type)) {
				return (T) new Short(param);
			}
			if ("java.lang.Long".equals(type) || "long".equals(type)) {
				return (T) new Long(param);
			}
			if ("java.lang.Boolean".equals(type) || "boolean".equals(type)) {
				return (T) new Boolean(param);
			}
		} catch (Exception e) {
		}
		return null;
	}

	/**
	 * 将传入的字符串数组参数转化成指定的数据类型的数组,如果格式不匹配则返回null
	 *
	 * @param param
	 *            要转换的参数字符串
	 * @param elementClass
	 *            转换的目标CLASS，一定是数组中元素的Class，而不是数组的Class
	 * @return
	 */
	private static Object convertArray(String[] param, Class elementClass) {
		if (param == null || elementClass == null) {
			return null;
		}
		// 获得要转换的数据类型名称
		String type = elementClass.getName();
		// 创建指定类型的数组对象
		Object array = Array.newInstance(elementClass, param.length);
		if ("java.lang.String".equals(type)) {
			return param;
		}
		if (type.equals(List.class.getName())) {
			//如果属性是List集合，则将字符串数组转换为LIst集合
			List list = Arrays.asList(param);
			return list;
		}


		try {// 根据不同类型的属性，返回不同的结果，如果出现异常，则返回null
			if ("java.util.Date".equals(type) || "java.sql.Date".equals(type)
					|| "java.sql.Timestamp".equals(type)) {
				for (int i = 0; i < param.length; i++) {
					Array.set(array,i, convert(param[i],elementClass));
				}
				return array;
			}
			if ("java.lang.Character".equals(type)) {

				for (int i = 0; i < param.length; i++) {
					Array.setChar(array, i, param[i].charAt(i));
				}
				return array;
			}
			if ("java.lang.Integer".equals(type) || "int".equals(type)) {
				for (int i = 0; i < param.length; i++) {
					Array.setInt(array, i, Integer.parseInt(param[i]));
				}
				return array;
			}
			if ("java.lang.Double".equals(type) || "double".equals(type)) {
				for (int i = 0; i < param.length; i++) {
					Array.setDouble(array, i, Double.parseDouble(param[i]));
				}
				return array;
			}
			if ("java.lang.Float".equals(type) || "float".equals(type)) {
				for (int i = 0; i < param.length; i++) {
					Array.setFloat(array, i, Float.parseFloat(param[i]));
				}
				return array;
			}
			if ("java.lang.Byte".equals(type) || "byte".equals(type)) {
				for (int i = 0; i < param.length; i++) {
					Array.setByte(array, i, Byte.parseByte(param[i]));
				}
				return array;
			}
			if ("java.lang.Short".equals(type) || "short".equals(type)) {
				for (int i = 0; i < param.length; i++) {
					Array.setShort(array, i, Short.parseShort(param[i]));
				}
				return array;
			}
			if ("java.lang.Long".equals(type) || "long".equals(type)) {
				for (int i = 0; i < param.length; i++) {
					Array.setLong(array, i, Long.parseLong(param[i]));
				}
				return array;
			}
			if ("java.lang.Boolean".equals(type) || "boolean".equals(type)) {
				for (int i = 0; i < param.length; i++) {
					Array.setBoolean(array, i, Boolean.parseBoolean(param[i]));
				}
				return array;
			}

		} catch (Exception e) {
		}
		return null;
	}

}
